#pragma once
#include<iostream>
#include<pthread.h>
#include<functional>

using std::cout;
using std::endl;
using std::cin;
using std::string;

template<typename T>
using func_t = std::function<void(T)>;

template<typename T>
class Thread
{
private:
    pthread_t _tid;
    string _thread_name;
    bool _isrunning;
    func_t<T> _func;
    T _data;
public:
    Thread<T> (func_t<T> __func,string __thread_name,T __data)
    :_func(__func),_thread_name(__thread_name),_isrunning(false),_tid(0),_data(__data)
    {}
    ~Thread()
    {}

    string ThreadName()
    {
        return _thread_name;
    }

    static void* ThreadRoutine(void * args)
    {  //pthread_create 函数第三个参数传入的函数指针必须是 void*(void*)的
       //但是成员函数自带this指针,相当于有第三个参数，所以需要修饰为static函数
        Thread *ts  =static_cast<Thread*>(args);
        //(void*)args;  //防止编译器告警
        ts->_func(ts->_data);
        return nullptr; 
    }

    bool Start()
    {
        int n = pthread_create(&_tid,nullptr,ThreadRoutine,this);
        if(n==0)
        {
            _isrunning = true;
            return true;
        }
        return false;
    }

    bool IsRunning()
    {
        return _isrunning;
    }

    bool Join()
    {
        if(!_isrunning) return true;
        int n = pthread_join(_tid,nullptr);
        if(n==0)
        {
            _isrunning = false;
            return true;
        }
        return false;
    }


};